package me.buick.util.jmeter.snmpvisualizers;

import static javax.swing.SwingConstants.CENTER;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;

import org.apache.jmeter.visualizers.MonitorModel;
import me.buick.util.snmp.core.pojo.NetworkInfoPojo;

public class SNMPNetworkIOOverviewPanel extends SNMPBorderedComponent{
	
	SNMPPlotterDigitalRecord plotter;

	private static final Dimension PREFERRED_PLOTTER_SIZE = new Dimension(300,
			200);
	private static final Dimension MINIMUM_PLOTTER_SIZE = new Dimension(200,
			150);
	
	private Map<String, Long> values_bak = new HashMap<String, Long>();
	
	private Map<String, SNMPPlotterDigitalRecord.Sequence> seqStore = new HashMap<String, SNMPPlotterDigitalRecord.Sequence>();

	// This is the default view range for all the overview plotters
	static final int VIEW_RANGE = -1; // Show all data
	private static final boolean IS_GTK = false;
	private Random rc = new Random();

	static Color PLOTTER_COLOR = IS_GTK ? new Color(231, 111, 80) : null;
	static Color PLOTTER_COLOR_W = IS_GTK ? new Color(231, 111, 80) : new Color(255, 111, 80);

	private JLabel infoLabel;
	private ColorTemplates ct = new ColorTemplates();

	public SNMPNetworkIOOverviewPanel() {
		super("Network IO (KiB Read/Write)");
		setLayout(new BorderLayout(0, 0));

		SNMPPlotterDigitalRecord plotter = new SNMPPlotterDigitalRecord();
		plotter.setPreferredSize(PREFERRED_PLOTTER_SIZE);
		plotter.setMinimumSize(MINIMUM_PLOTTER_SIZE);
		plotter.setViewRange(VIEW_RANGE);
		plotter.setUnit(SNMPPlotterDigitalRecord.Unit.BYTES);	
		setPlotter(plotter);
		this.plotter = plotter;
	}
	
	public SNMPPlotterDigitalRecord getPlotter() {
		return this.plotter;
	    }

	    public void setPlotter(SNMPPlotterDigitalRecord plotter) {
		this.plotter = plotter;
		setComponent(plotter);
	    }

	public void updateNetworkIOInfo(MonitorModel result) {
		
		SNMPMonitorModel snmpResult = (SNMPMonitorModel) result;
		
		Map<String, NetworkInfoPojo> pojos = snmpResult.getNetworkIO();
		
		Set<String> ifNameList = pojos.keySet();
		
		long[] values = new long[ifNameList.size()*2];
		int idx = 0;
		for(String ifName : ifNameList){
			SNMPPlotterDigitalRecord.Sequence tempSeqIn = seqStore.get(ifName+"/in");
			SNMPPlotterDigitalRecord.Sequence tempSeqOut = seqStore.get(ifName+"/out");
			if(tempSeqIn == null){
				tempSeqIn = plotter.createSequence(ifName+"/in", "Network "+ifName+" in", ct.getColor(),true);
				seqStore.put(ifName+"/in", tempSeqIn);
			}
			if(tempSeqOut == null)
			{
				tempSeqIn = plotter.createSequence(ifName+"/out", "Network "+ifName+" out", ct.getColor(),true);
				seqStore.put(ifName+"/out", tempSeqIn);
			}
			values[idx] = pojos.get(ifName).getIfInBytesPS();
			values[idx+1] = pojos.get(ifName).getIfOutBytesPS();
			if(values[idx] <= 0){
				Long dior = values_bak.get(ifName+"/in");
				if(dior != null && dior > 0){
						values[idx] = dior;
				}
			}else{
				values_bak.remove(ifName+"/in");
				values_bak.put(ifName+"/in",values[idx]);
			}
			if(values[idx+1] <= 0){
				Long diow = values_bak.get(ifName+"/out");
				if(diow != null && diow > 0){
					values[idx+1] = diow;
				}
			}else{
				values_bak.remove(ifName+"/out");
				values_bak.put(ifName+"/out",values[idx+1]);
			}
			idx = (++idx)+1;
		}
		getPlotter().addValues(snmpResult.getTimestamp(),values);
//		getPlotter().addValues(System.currentTimeMillis(),values);
	}

	public JLabel getInfoLabel() {
		if (infoLabel == null) {
			infoLabel = new JLabel("", CENTER) {
				@Override
				public void setText(String text) {
					if (text.startsWith("<html>")) {
						// Replace spaces with nbsp, except the
						// last one of two or more (to allow wrapping)
						StringBuilder buf = new StringBuilder();
						char[] chars = text.toCharArray();
						int n = chars.length;
						for (int i = 0; i < n; i++) {
							if (chars[i] == ' '
									&& ((i < n - 1 && chars[i + 1] == ' ') || ((i == 0 || chars[i - 1] != ' ') && (i == n - 1 || chars[i + 1] != ' ')))) {
								buf.append("&nbsp;");
							} else {
								buf.append(chars[i]);
							}
						}
						text = buf.toString();
					}
					super.setText(text);
				}
			};

			if (IS_GTK) {
				JPanel southPanel = new JPanel(new BorderLayout());
				JSeparator separator = new JSeparator(JSeparator.HORIZONTAL);
				southPanel.add(separator, BorderLayout.NORTH);
				southPanel.add(infoLabel, BorderLayout.SOUTH);
				add(southPanel, BorderLayout.SOUTH);
			} else {
				add(infoLabel, BorderLayout.SOUTH);
			}
		}
		return infoLabel;
	}

	public void clearData() {
		
		plotter.clearData();
		
		SNMPPlotterDigitalRecord plotter = new SNMPPlotterDigitalRecord();
		plotter.setPreferredSize(PREFERRED_PLOTTER_SIZE);
		plotter.setMinimumSize(MINIMUM_PLOTTER_SIZE);
		plotter.setViewRange(VIEW_RANGE);
		plotter.setUnit(SNMPPlotterDigitalRecord.Unit.BYTES);	
		setPlotter(plotter);
		this.seqStore.clear();
		ct.resetCounter();
	}
}
